/**
 * @addtogroup FXCRT
 * @{
 */

/**
 * @file
 * @brief Foxit Data Storage (FXDS), stores data along with type information
 */

#ifndef _FX_DS_H_
#define _FX_DS_H_

#ifndef _FX_SYSTEM_H_
#include "fx_system.h"
#endif

class CDS_Data;
class CDS_Integer;
class CDS_Decimal;
class CDS_Text;
class CDS_Image;
class CDS_DateTime;
class CDS_Variant;
class CDS_Array;
class CDS_Rowset;

#define FX_CONVERTOR(DestType, SrcType) \
		DestType(SrcType srcData) { Init(); operator=(srcData); } \
		DestType& operator = (SrcType srcData);

/////////////////////////////////////////////////////////////////
// Data Type Codes
#define FXTYPE_INVALID		0	// Invalid data type
#define FXTYPE_INTEGER		1	// Signed integer number
#define FXTYPE_DECIMAL		2	// Exact amount decimal
#define FXTYPE_TEXT			3	// Unlimited text string (zero-terminated)
#define FXTYPE_IMAGE		4	// Unlimited binary image
#define FXTYPE_DATETIME		5	// Date/time
#define FXTYPE_LOCALTEXT	7	// Local text string
#define FXTYPE_VARIANT		6	// Any of the above type

// Error codes
#define FXERR_DS_NULLDATA		1	// Null data when doing data conversion
#define FXERR_DS_DATATYPE		2	// Imcompatible data type for conversion
#define FXERR_DS_FORMAT		3	// Invalid data format while converting
#define FXERR_DS_OVERFLOW		4	// Data value overflow
#define FXERR_DS_ARRAYINDEX	5	// Invalid array index
#define FXERR_DS_TEXTFORMAT	6	// CFX_Text::Format error, please check format string
#define FXERR_DS_OUTOFCOLUMN 7	// Column number out of range
#define FXERR_DS_OUTOFROW	8	// Row number out of range

/////////////////////////////////////////////////////////////////
// Base class for all data types
class CDS_Data
{
public:
	FX_BOOL		IsNull() const;
	void		SetNull();

	typedef enum {Invalid, Integer, Decimal, Text, Image, DateTime, Variant} DataType;

	DataType	GetType() const { return m_iDataType; }

	void		Init(DataType Type);	// Internal use
	void		InitCopy(void* pdest);	// Internal use
	void		Free();					// Internal use

	static	CDS_Data*	Create(DataType iDataType);	// Create a data object
	CDS_Data*	Clone() const;		// Clone this data
	void		Destroy();			// Destroy the data object

	CDS_Text	GetText() const;	// Get display string
	void		ConvertFrom(const CDS_Data& rAnotherData);

#ifdef WIN32
	void operator >> (VARIANT& rVariantVariable) const;
#endif

	// Comparism: (Note: if the two operators have different underlying 
	// data type, the comparing data type will be same as the first operator)
	long		Compare(const CDS_Data&) const;
	bool		operator == (const CDS_Data& rAnotherData) const;
	bool		operator != (const CDS_Data& rAnotherData) const;
	bool		operator > (const CDS_Data& rAnotherData) const;
	bool		operator >= (const CDS_Data& rAnotherData) const;
	bool		operator < (const CDS_Data& rAnotherData) const;
	bool		operator <= (const CDS_Data& rAnotherData) const;

	// Comparism with string (compare by the default display format, using Unicode)
	long		Compare(FX_LPCWSTR) const;
	bool		operator == (FX_LPCWSTR) const;
	bool		operator != (FX_LPCWSTR) const;
	bool		operator > (FX_LPCWSTR) const;
	bool		operator >= (FX_LPCWSTR) const;
	bool		operator < (FX_LPCWSTR) const;
	bool		operator <= (FX_LPCWSTR) const;

protected:
	CDS_Data() {}

	DataType	m_iDataType;

	long	InternalSize() const;
};


#endif //  _FX_DS_H_

/** @} */
